/**
 *
 */
package com.cmcc.xdr.pcapparse.tcp.http;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.CharsetDecoder;

import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.MessageConstraints;
import org.apache.http.impl.ConnSupport;
import org.apache.http.impl.DefaultHttpRequestFactory;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.io.DefaultHttpRequestParser;
import org.apache.http.impl.io.DefaultHttpRequestParserFactory;
import org.apache.http.impl.io.DefaultHttpResponseParser;
import org.apache.http.impl.io.HttpTransportMetricsImpl;
import org.apache.http.impl.io.SessionInputBufferImpl;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicLineParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
//
//import com.cmcc.packet.appdistinguish.AppInfo;
//import com.cmcc.packet.appdistinguish.HttpProto;
//import com.cmcc.packet.capture.JCaptures;

/**
 * @Date 2018年1月19日 下午7:33:50
 * @author Amish
 *
 */
public class HttpDecoder {
	private static Logger logger = LogManager.getLogger(HttpDecoder.class);
	
	public static HttpRequest decodeRequest(byte[] httpByte) throws Exception{
		try {
			//logger.info("data byte[] to string :\n"+new String(httpByte,"ascii").substring(0, 100));//TODO 临时截取
			//logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"+new String(httpByte,"ascii").substring(0, 200));//TODO 临时截取
			logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"+new String(httpByte,"ascii"));//TODO 临时截取
			logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
		} catch (UnsupportedEncodingException e1) {
			// TODO 自动生成的 catch 块
			e1.printStackTrace();
		}

		
		ByteArrayInputStream inputStream = new ByteArrayInputStream(httpByte);//模拟ServerSocket.getInputStream
		
		CharsetDecoder chardecoder = ConnSupport.createDecoder(ConnectionConfig.DEFAULT);
		//CharsetEncoder charencoder = ConnSupport.createEncoder(ConnectionConfig.DEFAULT);
		HttpTransportMetricsImpl inTransportMetrics = new HttpTransportMetricsImpl();
        //HttpTransportMetricsImpl outTransportMetrics = new HttpTransportMetricsImpl();
		
		/**
		 * SessionInputBufferImpl
		 */
		int buffersize = httpByte.length;
		
		SessionInputBufferImpl inbuffer = new SessionInputBufferImpl(inTransportMetrics, buffersize, -1,MessageConstraints.DEFAULT, chardecoder);
		inbuffer.bind(inputStream);
		
		/**
		 * DefaultHttpRequestParser
		 */
		DefaultHttpRequestParser defaultHttpRequestParser = new DefaultHttpRequestParser(inbuffer, BasicLineParser.INSTANCE, DefaultHttpRequestFactory.INSTANCE, MessageConstraints.DEFAULT);
		
		HttpRequest request = null;
		try {
			request = defaultHttpRequestParser.parse();
			logger.debug("HTTPDecoder HttpRequest headers num :"+request.getAllHeaders().length);
			logger.debug("HTTPDecoder HttpRequest to string :"+request.toString());
			
			
//			logger.info(request.getRequestLine().getUri());
//			Header header = request.getFirstHeader("Content-Type");
//			if(header!=null)
//			    logger.info(header.getValue());
//			Header header1 = request.getFirstHeader("User-Agent");
//			if(header1!=null)
//			    logger.info(header1.getValue());

			
			
		} catch (Exception e) {
            throw e;
		} 
		
		return request;
	}
	
	public static HttpResponse decodeResponse(byte[] httpByte) throws Exception{
		
		ByteArrayInputStream inputStream = new ByteArrayInputStream(httpByte);
		
		CharsetDecoder chardecoder = ConnSupport.createDecoder(ConnectionConfig.DEFAULT);
		HttpTransportMetricsImpl inTransportMetrics = new HttpTransportMetricsImpl();
		
		/**
		 * SessionInputBufferImpl
		 */
		int buffersize = httpByte.length;
		
		SessionInputBufferImpl inbuffer = new SessionInputBufferImpl(inTransportMetrics, buffersize, -1,MessageConstraints.DEFAULT, chardecoder);
		inbuffer.bind(inputStream);
		
		DefaultHttpResponseParser defaultHttpResponseParser = new DefaultHttpResponseParser(inbuffer, BasicLineParser.INSTANCE, DefaultHttpResponseFactory.INSTANCE, MessageConstraints.DEFAULT);
		HttpResponse response = null;
		try {
			response = defaultHttpResponseParser.parse();
			logger.debug("HTTPDecoder HttpResponse headers num :"+response.getAllHeaders().length);
			logger.debug("HTTPDecoder HttpResponse to string :"+response.toString());
						
		} catch (Exception e) {
			throw e;
		}
		
		return response;
	}

}
